package service

import (
	"errors"
	"fmt"
	"gitee.com/hakwolf/taibak/internal/modules/logger"
	"gitee.com/hakwolf/taibak/internal/modules/utils"
	"golang.org/x/net/context"
	"sync"
	"time"
)

var (
	taskMap sync.Map
)

var (
	errUnavailable = errors.New("无法连接远程服务器")
)

func generateTaskUniqueKey(ip string, port int64, id int64) string {
	return fmt.Sprintf("%s:%d:%d", ip, port, id)
}

func Stop(ip string, port int64, id int64) {
	key := generateTaskUniqueKey(ip, port, id)
	cancel, ok := taskMap.Load(key)
	if !ok {
		return
	}
	cancel.(context.CancelFunc)()
}

//func Exec(ip string, port int64, taskReq *pb.TaskRequest) (string, error) {
//	defer func() {
//		if err := recover(); err != nil {
//			logger.Error("panic#rpc/client.go:Exec#", err)
//		}
//	}()
//	addr := fmt.Sprintf("%s:%d", ip, port)
//	c, err := grpcpool.Pool.Get(addr)
//	if err != nil {
//		return "", err
//	}
//	if taskReq.Timeout <= 0 || taskReq.Timeout > 86400 {
//		taskReq.Timeout = 86400
//	}
//	timeout := time.Duration(taskReq.Timeout) * time.Second
//	ctx, cancel := context.WithTimeout(context.Background(), timeout)
//	defer cancel()
//
//	taskUniqueKey := generateTaskUniqueKey(ip, port, taskReq.Id)
//	taskMap.Store(taskUniqueKey, cancel)
//	defer taskMap.Delete(taskUniqueKey)
//
//	resp, err := c.Run(ctx, taskReq)
//	if err != nil {
//		return parseGRPCError(err)
//	}
//
//	if resp.Error == "" {
//		return resp.Output, nil
//	}
//
//	return resp.Output, errors.New(resp.Error)
//}

func ExecDb(ip string, port int64, taskReq *utils.DbTaskRequest) (string, error) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error("panic#rpc/client.go:Exec#", err)
		}
	}()
	//addr := fmt.Sprintf("%s:%d", ip, port)
	//c, err := grpcpool.Pool.Get(addr)
	//if err != nil {
	//	return "", err
	//}
	if taskReq.Timeout <= 0 || taskReq.Timeout > 86400 {
		taskReq.Timeout = 86400
	}
	timeout := time.Duration(taskReq.Timeout) * time.Second
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	taskUniqueKey := generateTaskUniqueKey(ip, port, taskReq.Id)
	taskMap.Store(taskUniqueKey, cancel)
	defer taskMap.Delete(taskUniqueKey)

	s := Server{}
	resp, err := s.DbRun(ctx, taskReq) //c.DbRun(ctx, taskReq)
	if err != nil {
		//return parseGRPCError(err)
	}

	if resp.Error == "" {
		return resp.Output, nil
	}

	return resp.Output, errors.New(resp.Error)
}

//func parseGRPCError(err error) (string, error) {
//	switch status.Code(err) {
//	case codes.Unavailable:
//		return "", errUnavailable
//	case codes.DeadlineExceeded:
//		return "", errors.New("执行超时, 强制结束")
//	case codes.Canceled:
//		return "", errors.New("手动停止")
//	}
//	return "", err
//}
